package com.xiaodu.acer.phoneplay.widget;

import android.content.Context;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jakewharton.rxbinding2.view.RxView;
import com.orhanobut.logger.Logger;
import com.xiaodu.acer.phoneplay.R;
import com.xiaodu.acer.phoneplay.bean.AppDownloadInfo;
import com.xiaodu.acer.phoneplay.bean.AppInfo;
import com.xiaodu.acer.phoneplay.bean.downloadbean.DownloadMission;
import com.xiaodu.acer.phoneplay.bean.downloadbean.OtherStatus;
import com.xiaodu.acer.phoneplay.common.Constant;
import com.xiaodu.acer.phoneplay.common.rx.RxHttpReponseCompat;
import com.xiaodu.acer.phoneplay.common.rx.subscriber.RxSchedulers;
import com.xiaodu.acer.phoneplay.common.util.AppStoreUtil;
import com.xiaodu.acer.phoneplay.common.util.AppUtils;
import com.xiaodu.acer.phoneplay.common.util.PermissionUtil;

import java.io.File;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import library.base.BaseBean;
import library.util.ACache;
import retrofit2.Retrofit;
import retrofit2.http.GET;
import retrofit2.http.Path;
import zlc.season.rxdownload3.RxDownload;
import zlc.season.rxdownload3.core.Deleted;
import zlc.season.rxdownload3.core.Downloading;
import zlc.season.rxdownload3.core.Failed;
import zlc.season.rxdownload3.core.Normal;
import zlc.season.rxdownload3.core.Status;
import zlc.season.rxdownload3.core.Succeed;
import zlc.season.rxdownload3.core.Suspend;
import zlc.season.rxdownload3.core.Waiting;
import zlc.season.rxdownload3.extension.ApkInstallExtension;

import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;


public class DownloadButtonConntroller {

    private Api mApi;
    private RxDownload rxDownload;


    public DownloadButtonConntroller(Retrofit retrofit) {
        rxDownload = RxDownload.INSTANCE;
        mApi = retrofit.create(Api.class);

    }


    /**
     * 外界去调用，下载的功能
     *
     * @param btn
     */
    public void handClick(DownloadProgressButton btn, DownloadMission mission) {
        //TODO 某些情况下等status状态未更新为1时，会触发自动下载(已解决)
        rxDownload.create(mission)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DownloadConsumer(btn, mission));
    }


    public void handClick(final DownloadProgressButton btn, final AppInfo appInfo) {
        if (mApi == null) {
            return;
        }
        isAppInstalled(btn.getContext(), appInfo)
                .flatMap(new Function<Status, ObservableSource<Status>>() {
                    @Override
                    public ObservableSource<Status> apply(@NonNull Status status)
                            throws Exception {
                        if (status instanceof OtherStatus.UnInstall) {
                            return isApkFileExsit(btn.getContext(), appInfo);
                        }
                        return Observable.just(status);
                    }
                })
                .flatMap(new Function<Status, ObservableSource<Status>>() {
                    @Override
                    public ObservableSource<Status> apply(@NonNull Status status) throws Exception {
                        if (status instanceof OtherStatus.Exists) {
                            return getAppDownloadInfo(appInfo.getId())
                                    .flatMap(new Function<AppDownloadInfo, ObservableSource<Status>>() {
                                        @Override
                                        public ObservableSource<Status> apply(@NonNull AppDownloadInfo appDownloadInfo) throws Exception {
                                            appInfo.setAppDownloadInfo(appDownloadInfo);
                                            return rxDownload.create(AppStoreUtil.appInfoToMission(appInfo, btn.getContext()))
                                                    .observeOn(AndroidSchedulers.mainThread())
                                                    .toObservable();
                                        }
                                    });
                        }
                        //不存在 则返回原来的状态，没安装 也没文件 就是普通待下载
                        return Observable.just(status);
                    }
                })
                .compose(RxSchedulers.<Status>io_main())
                .subscribe(new DownloadConsumer(btn, AppStoreUtil.appInfoToMission(appInfo, btn.getContext())));
    }


    private Observable<Status> isApkFileExsit(Context context, AppInfo appInfo) {
        String path = ACache.get(context).getAsString(Constant.APK_DOWNLOAD_DIR) + File.separator +
                appInfo.getReleaseKeyHash() + ".download";
        File file = new File(path);
        Status status = (file.exists() ? new OtherStatus.Exists() : new Normal(new Status(0, 0, true)));
        return Observable.just(status);
    }


    private Observable<Status> isAppInstalled(Context context, AppInfo appInfo) {
        Gson gson = new Gson();
        String json = ACache.get(context).getAsString(Constant.APP_UPDATE_LIST);
        List<AppInfo> apps = gson.fromJson(json, new TypeToken<List<AppInfo>>() {
        }.getType());

        Status status = AppUtils.isInstalled(context, appInfo.getPackageName()) ?
                new OtherStatus.Installed() : new OtherStatus.UnInstall();

        if (apps == null) {
            return Observable.just(status);
        }

        if (status instanceof OtherStatus.Installed) {
            for (AppInfo a : apps) {
                if (a.getPackageName().equals(appInfo.getPackageName())) {
                    status = new OtherStatus.NeedUpgrade();
                }
            }
        }
        return Observable.just(status);
    }



    /**
     * 如果没有下载，开始下载
     *
     * @return
     */
    private Observable<AppDownloadInfo> getAppDownloadInfo(int id) {
        return mApi.getAppDownloadInfo(id).compose(RxHttpReponseCompat.<AppDownloadInfo>compatResult());
    }

    private void bindClick(final DownloadProgressButton btn, final DownloadMission mission) {
        RxView.clicks(btn).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                Status status = (Status) btn.getTag(R.id.tag_apk_flag);
                //暂停和普通状态均是下载 并需要监听按钮状态
                if (status instanceof Normal) {
                    startDownload(mission, btn);
                } else if (status instanceof Suspend) {
                    startDownload(mission, btn);
                } else if (status instanceof Waiting) {
                    btn.setText("耐心等待");
                } else if (status instanceof Downloading) {
                    pauseDownload(mission);
                } else if (status instanceof Failed) {
                    startDownload(mission, btn);
                } else if (status instanceof Succeed) {
                    installApp(btn.getContext(), mission);
                } else if (status instanceof OtherStatus.Installed ||
                        status instanceof ApkInstallExtension.Installed) {
                    runApp(btn.getContext(), mission.getPackageName());
                } else if (status instanceof OtherStatus.NeedUpgrade) {
                    startDownload(mission, btn);
                } else if (status instanceof Deleted) {
                    startDownload(mission, btn);
                } else {
                    Logger.e("未知状态");
                }

            }
        });
    }


    /**
     * 传到这里的返回值
     */
    class DownloadConsumer implements Consumer<Status> {

        DownloadProgressButton btn;
        DownloadMission mission;

        DownloadConsumer(DownloadProgressButton button, DownloadMission mission) {
            this.btn = button;
            this.mission = mission;
        }

        @Override
        public void accept(Status status) {
            btn.setTag(R.id.tag_apk_flag, status);
            bindClick(btn, mission);

            if (status instanceof Normal) {
                //自动下载标志位
                if (!"NONE".equals(mission.getUrl()) && mission.getNeedAutoStart() == 1) {
                    //创建任务后无论什么情况均不需要自动开始
                    mission.setNeedAutoStart(0);
                    rxDownload.start(mission).subscribe();
                }
                btn.download();
            } else if (status instanceof Suspend) {
                btn.setProgress((int) (status.getDownloadSize() * 100 / status.getTotalSize()));
                btn.paused();
            } else if (status instanceof Waiting) {
                btn.setText("等待中");
            } else if (status instanceof Downloading) {
                btn.setProgress((int) (status.getDownloadSize() * 100 / status.getTotalSize()));
            } else if (status instanceof Failed) {
                btn.setText("失败重试");
            } else if (status instanceof Succeed) {
                btn.setText("安装");
            } else if (status instanceof OtherStatus.Installed || status instanceof ApkInstallExtension.Installed) {
                btn.setText("运行");
            } else if (status instanceof OtherStatus.NeedUpgrade) {
                btn.setText("升级");
            } else if (status instanceof Deleted) {
                btn.setText("重新下载");
            }

        }
    }

    /**
     * 开始下载
     *
     * @param btn
     */
    private void startDownload(final DownloadMission mission, final DownloadProgressButton btn) {

        PermissionUtil.requestPermisson(btn.getContext(), WRITE_EXTERNAL_STORAGE)
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            //如果没有地址，就先找出地址开始下载
                            if ("NONE".equals(mission.getUrl())) {
                                getAppDownloadInfo(mission.getId()).flatMap(new Function<AppDownloadInfo, ObservableSource<Status>>() {
                                    @Override
                                    public ObservableSource<Status> apply(@NonNull AppDownloadInfo appDownloadInfo) throws Exception {
                                        mission.setUrl(appDownloadInfo.getDownloadUrl());
                                        //因为没有下载记录 所以链接为空，重新从服务器获取后 创建任务并需要自动开始下载 设置值1 创建任务后无论什么情况均不需要自动开始
                                        mission.setNeedAutoStart(1);
                                        return rxDownload.create(mission)
                                                .observeOn(AndroidSchedulers.mainThread())
                                                .toObservable();
                                    }
                                }).subscribe(new DownloadConsumer(btn, mission));
                            } else {//如果已经有地址了，先进行下载
                                start(mission);
                            }
                        }


                    }
                });

    }

    public void start(DownloadMission mission) {
        rxDownload.start(mission)
                .subscribe();
    }

    /**
     * 安装apk
     *
     * @param context
     * @param mission
     */
    private void installApp(Context context, DownloadMission mission) {
        File apk = new File(mission.getSavePath());
        if (!apk.exists()) {
            rxDownload.delete(mission, true).subscribe();
        }
        AppUtils.installApk(context, apk.getPath());

        //    RxDownload.INSTANCE.extension(mission, ApkInstallExtension.class).subscribe();

    }


    public interface Api {
        @GET("download/{id}")
        Observable<BaseBean<AppDownloadInfo>> getAppDownloadInfo(@Path("id") int id);
    }

    //运行app
    private void runApp(Context context, String packageName) {
        AppUtils.runApp(context, packageName);
    }

    /**
     * 暂停(停止)下载
     *
     * @param mission 如果是mission，统一都是mission
     */
    private void pauseDownload(DownloadMission mission) {
        rxDownload.stop(mission).subscribe();
    }


}
